#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "base.h"

#include "include/workflow.h"

pthread_mutexattr_t pmuattrMp;
pthread_mutex_t pmuMp;
pthread_condattr_t pconattrMp;
pthread_cond_t pconMp;

BOOL listenFlag;


int main_t(int argc, char ** argv) {
	pid_t pid, sid;
	dLinkList *p_pl;
	pthread_attr_t ptAttr;
	pthread_t ptListen;
	int ret;

	ASSERT(argc>=2);

	pid = fork();

	if (pid < 0) {
		printf("Cannot fork new process. Exiting..\n");
		exit(EXIT_FAILURE);
	}

	/**< Exit the parent process*/
	if (pid > 0) {
		exit(EXIT_SUCCESS);
	}

	/**< Turn off the mask */
	umask(0);

	/**< Create new session id and quit from the parent process
	 Become the new  */
	sid = setsid();
	if (sid < 0) {
		/* Log any failure */
		exit(EXIT_FAILURE);
	}

	/**< Change to working directory to root */
	if ((chdir("/")) < 0) {
		/* Log any failure here */
		exit(EXIT_FAILURE);
	}
	/* Close out the standard file descriptors */
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	/**< Initialize conf parameters and load them into memory */
	if (FALSE == initConf(argv[1])) {
		exit(EXIT_FAILURE);
	}
	logIt(LOG_INFO, "Finish initializing configurations");

	/**< Load plugins for daemon */

	if (NULL == (p_pl = initPlugins(getCurrentConfHtab()))) {
		logIt(LOG_ERROR, "Intializing plugins failed.");
		logIt(LOG_ERROR, "WASD exiting due to fatal error");
		exit(EXIT_FAILURE);
	}


	pthread_mutexattr_init(&pmuattrMp);
	/*Process private p mutex*/
	pthread_mutexattr_setpshared(&pmuattrMp,PTHREAD_PROCESS_PRIVATE);
	/* Check deadlocks return error if you want to lock a mutext which is already locked.*/
	pthread_mutexattr_settype(&pmuattrMp,PTHREAD_MUTEX_ERRORCHECK);
	pthread_mutex_init(&pmuMp,&pmuattrMp);

	pthread_condattr_init(&pconattrMp);
	/* process private*/
	pthread_condattr_setpshared(&pconattrMp, PTHREAD_PROCESS_PRIVATE);
	pthread_cond_init(&pconMp);

	/**< Daemon initialization
	 !!!!
	 */

	/**< Load plugins for scheduling flows */

	/*	if(FALSE==loadWFlowPlugin_EX(getConfItem("WASD_SCHEDULE_PLUGIN_PATH"))){
	 logIt(LOG_ERROR,"Load Flow plugins failed.Exiting..");
	 closeConf(getCurrentConfHtab());
	 exit(EXIT_FAILURE);
	 }*/

	/**< Recover from last run */

	/**< Read current stored flow structures into memory */

	/**< Open a thread for listening to port XXXX which will accept connections from clients */
	pthread_attr_init(&ptAttr);
	ret = pthread_attr_setdetachstate(&ptAttr,PTHREAD_CREATE_DETACHED);
	if(0!=ret){

	}

	listenFlag=TRUE;
	pthread_create(&ptListen,&ptAttr,handleClientReq,NULL);
	pthread_mutex_lock(&pmuMp);
	pthread_cond_wait(&pconMp,&pmuMp);
	pthread_mutex_unlock(&pmuMp);

	if(FALSE==listenFlag){
		logIt(LOG_ERROR,"The daemon has stopped because of listenFlag.");
		exit(EXIT_FAILURE);
	}



	/**< Big loop */
	/*
	 *
	 * ToDO:
	 * 1. Check listenFlag. If it's FALSE which means the listenOnClient Thread exits, the main process will exit
	 *
	 *
	 * */

	/*	while(1){

	 *< Refresh flow table
	 * a. Check whether there's a time-based trigger available
	 * b.
	 * (Fetch new flow info)

	 *< Check flow status

	 *< Schedule flow

	 }*/

	/*	freeWorkFlowPlugin(getWorkFlowPlugin());*/
	closeConf(getCurrentConfHtab());

	exit(EXIT_SUCCESS);

}
